Skip to content

Commit 7ee0b44

Browse files
authored
feat: add signal resource adapter package
Adds provider-neutral @threadplane/signal-resource package for signal-backed chat resources. Exposes toAgent, DI helpers, structural resource types, README, API docs, and workspace path metadata. Includes adapter conformance, DI, and type tests, plus release and CI metadata for the new publishable package.
1 parent 448503d commit 7ee0b44

31 files changed

Lines changed: 1817 additions & 9 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
if: github.event_name == 'push' || needs.ci-scope.outputs.library == 'true'
8383
runs-on: ubuntu-latest
8484
env:
85-
LIBS: chat,langgraph,ag-ui,render,a2ui,licensing,telemetry
85+
LIBS: chat,langgraph,ag-ui,render,a2ui,licensing,signal-resource,telemetry
8686
steps:
8787
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
8888
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0

.github/workflows/publish.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
contents: read
2929
id-token: write # required for npm trusted publishing + provenance
3030
env:
31-
NPM_PUBLISHABLE_PROJECTS: chat,langgraph,ag-ui,render,a2ui,licensing,telemetry
31+
NPM_PUBLISHABLE_PROJECTS: chat,langgraph,ag-ui,render,a2ui,licensing,signal-resource,telemetry
3232
steps:
3333
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3434
# Node 24 ships npm 11+ which fully implements npm trusted publishing
@@ -57,10 +57,10 @@ jobs:
5757
run: npx nx run-many -t lint,test,build --projects=$NPM_PUBLISHABLE_PROJECTS --skip-nx-cache
5858

5959
- name: Patch install telemetry into publishable manifests
60-
run: node libs/telemetry/scripts/apply-install-telemetry.mjs dist/libs/chat dist/libs/langgraph dist/libs/ag-ui dist/libs/render dist/libs/a2ui dist/libs/licensing
60+
run: node libs/telemetry/scripts/apply-install-telemetry.mjs dist/libs/chat dist/libs/langgraph dist/libs/ag-ui dist/libs/render dist/libs/a2ui dist/libs/licensing dist/libs/signal-resource
6161

6262
- name: Verify install telemetry in publishable manifests
63-
run: node libs/telemetry/scripts/verify-install-telemetry.mjs dist/libs/chat dist/libs/langgraph dist/libs/ag-ui dist/libs/render dist/libs/a2ui dist/libs/licensing dist/libs/telemetry
63+
run: node libs/telemetry/scripts/verify-install-telemetry.mjs dist/libs/chat dist/libs/langgraph dist/libs/ag-ui dist/libs/render dist/libs/a2ui dist/libs/licensing dist/libs/signal-resource dist/libs/telemetry
6464

6565
- name: Verify atomic release versions
6666
run: node scripts/verify-release-versions.mjs --tag "$RELEASE_TAG"

.github/workflows/release-provenance.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
hashes: ${{ steps.hash.outputs.hashes }}
3434
tag: ${{ steps.tag.outputs.tag }}
3535
env:
36-
NPM_PUBLISHABLE_PROJECTS: chat,langgraph,ag-ui,render,a2ui,licensing,telemetry
36+
NPM_PUBLISHABLE_PROJECTS: chat,langgraph,ag-ui,render,a2ui,licensing,signal-resource,telemetry
3737
steps:
3838
- name: Resolve target tag
3939
id: tag
@@ -53,7 +53,7 @@ jobs:
5353
- name: Pack tarballs
5454
run: |
5555
mkdir -p release-artifacts
56-
for p in chat langgraph ag-ui render a2ui licensing telemetry; do
56+
for p in chat langgraph ag-ui render a2ui licensing signal-resource telemetry; do
5757
npm pack "dist/libs/$p" --pack-destination release-artifacts
5858
done
5959
- name: Generate subject hashes
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
[
2+
{
3+
"name": "SignalChatResourceLike",
4+
"kind": "interface",
5+
"description": "Minimal structural contract required to adapt a signal-backed chat resource.",
6+
"properties": [
7+
{
8+
"name": "error",
9+
"type": "Signal<Error | undefined>",
10+
"description": "Current resource error, if any.",
11+
"optional": false
12+
},
13+
{
14+
"name": "isLoading",
15+
"type": "Signal<boolean>",
16+
"description": "Whether the resource is currently producing a response.",
17+
"optional": false
18+
},
19+
{
20+
"name": "reload",
21+
"type": "() => boolean",
22+
"description": "Reload the resource, used as a fallback for `Agent.regenerate()`.",
23+
"optional": true
24+
},
25+
{
26+
"name": "resendMessages",
27+
"type": "() => void",
28+
"description": "Re-run against the current history, if supported by the resource.",
29+
"optional": true
30+
},
31+
{
32+
"name": "sendMessage",
33+
"type": "(message: object) => void",
34+
"description": "Send a new user message.",
35+
"optional": false
36+
},
37+
{
38+
"name": "setMessages",
39+
"type": "(messages: SignalChatResourceMessage[]) => void",
40+
"description": "Replace resource message history. Used by `Agent.regenerate()`.",
41+
"optional": false
42+
},
43+
{
44+
"name": "stop",
45+
"type": "() => void",
46+
"description": "Stop the current response. Called only while `isLoading()` is true.",
47+
"optional": false
48+
},
49+
{
50+
"name": "value",
51+
"type": "Signal<SignalChatResourceMessage[]>",
52+
"description": "Current resource message history.",
53+
"optional": false
54+
}
55+
],
56+
"examples": []
57+
},
58+
{
59+
"name": "SignalChatResourceToolCall",
60+
"kind": "interface",
61+
"description": "Tool-call shape exposed by a signal-backed chat resource.",
62+
"properties": [
63+
{
64+
"name": "args",
65+
"type": "unknown",
66+
"description": "Parsed tool arguments.",
67+
"optional": false
68+
},
69+
{
70+
"name": "name",
71+
"type": "string",
72+
"description": "Tool name shown in Threadplane tool-call UI.",
73+
"optional": false
74+
},
75+
{
76+
"name": "result",
77+
"type": "PromiseSettledResult<unknown>",
78+
"description": "Settled tool result, when the resource exposes one.",
79+
"optional": true
80+
},
81+
{
82+
"name": "status",
83+
"type": "\"pending\" | \"done\"",
84+
"description": "Resource-specific lifecycle state for the tool call.",
85+
"optional": false
86+
},
87+
{
88+
"name": "toolCallId",
89+
"type": "string",
90+
"description": "Stable identifier for linking assistant messages to tool-call details.",
91+
"optional": false
92+
}
93+
],
94+
"examples": []
95+
},
96+
{
97+
"name": "SignalChatResourceMessage",
98+
"kind": "type",
99+
"description": "Message shape consumed by the signal-resource adapter.",
100+
"signature": "object | object | object",
101+
"examples": []
102+
},
103+
{
104+
"name": "SignalResourceAgentSource",
105+
"kind": "type",
106+
"description": "Resource instance or factory accepted by `provideAgent()`.",
107+
"signature": "SignalChatResourceLike | () => SignalChatResourceLike",
108+
"examples": []
109+
},
110+
{
111+
"name": "injectAgent",
112+
"kind": "function",
113+
"description": "Injects the signal-resource-backed Agent registered by provideAgent().",
114+
"signature": "injectAgent(): Agent<>",
115+
"params": [],
116+
"returns": {
117+
"type": "Agent<>",
118+
"description": ""
119+
},
120+
"examples": [
121+
"```ts\nimport { injectAgent } from '@threadplane/signal-resource';\n\nconst agent = injectAgent();\n```"
122+
]
123+
},
124+
{
125+
"name": "provideAgent",
126+
"kind": "function",
127+
"description": "Provides a signal-resource-backed Agent through Angular dependency injection.",
128+
"signature": "provideAgent(ref: AgentRef<T>, sourceOrFactory: SignalResourceAgentSource): Provider[]",
129+
"params": [
130+
{
131+
"name": "ref",
132+
"type": "AgentRef<T>",
133+
"description": "",
134+
"optional": false
135+
},
136+
{
137+
"name": "sourceOrFactory",
138+
"type": "SignalResourceAgentSource",
139+
"description": "",
140+
"optional": false
141+
}
142+
],
143+
"returns": {
144+
"type": "Provider[]",
145+
"description": ""
146+
},
147+
"examples": [
148+
"```ts\nimport { provideAgent } from '@threadplane/signal-resource';\n\nbootstrapApplication(AppComponent, {\n providers: [provideAgent(() => resource)],\n});\n```"
149+
]
150+
},
151+
{
152+
"name": "toAgent",
153+
"kind": "function",
154+
"description": "Wrap a signal-backed chat resource in the runtime-neutral Agent contract.",
155+
"signature": "toAgent(resource: SignalChatResourceLike): Agent<>",
156+
"params": [
157+
{
158+
"name": "resource",
159+
"type": "SignalChatResourceLike",
160+
"description": "",
161+
"optional": false
162+
}
163+
],
164+
"returns": {
165+
"type": "Agent<>",
166+
"description": ""
167+
},
168+
"examples": [
169+
"```ts\nimport { toAgent } from '@threadplane/signal-resource';\n\nconst agent = toAgent(resource);\n```"
170+
]
171+
}
172+
]

apps/website/scripts/generate-api-docs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const LIBRARIES: LibraryEntryConfig[] = [
182182
{ docSlug: 'chat', entryPoints: ['libs/chat/src/public-api.ts', 'libs/chat/testing/public-api.ts'] },
183183
{ docSlug: 'render', entryPoints: ['libs/render/src/public-api.ts'] },
184184
{ docSlug: 'ag-ui', entryPoints: ['libs/ag-ui/src/public-api.ts'] },
185+
{ docSlug: 'signal-resource', entryPoints: ['libs/signal-resource/src/public-api.ts'] },
185186
{ docSlug: 'a2ui', entryPoints: ['libs/a2ui/src/index.ts'] },
186187
{ docSlug: 'middleware', entryPoints: ['libs/middleware/src/langgraph/index.ts'] },
187188
{ docSlug: 'licensing', entryPoints: ['libs/licensing/src/index.ts'] },

0 commit comments

Comments
 (0)